package me.moscrop.RootCommand.utilities;

import java.lang.reflect.Array;
import java.util.LinkedList;
import java.util.List;

import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.Chicken;
import org.bukkit.entity.Cow;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Pig;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Player;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Squid;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zombie;

public class Utility {
	
	public static Location getSafeLocationAt(Block block){
		Location location = new Location(block.getWorld(), block.getX() + 0.5, block.getY(), block.getZ() + 0.5);

		return getSafeLocationAt(location);
	}

	public static Location getSafeLocationAt(Player player){
		return getSafeLocationAt(player.getLocation());
	}
	
	public static Location getSafeLocationAt(Location location){
		
		for(int y = location.getBlockY(); y < 125; y++){
			location.setY(y);
			
			if(location.getBlock().getType().equals(Material.AIR) && location.getBlock().getRelative(BlockFace.UP).getType().equals(Material.AIR)){
				return location;
			}
		}
		
		location.setY(127);
		return location;
	}
	
	public static String replaceColor(String string){
		return string
		.replace("&4", ChatColor.DARK_RED.toString())
		.replace("&c", ChatColor.RED.toString())
		.replace("&6", ChatColor.GOLD.toString())
		.replace("&e", ChatColor.YELLOW.toString())
		.replace("&2", ChatColor.DARK_GREEN.toString())
		.replace("&a", ChatColor.GREEN.toString())
		.replace("&b", ChatColor.AQUA.toString())
		.replace("&3", ChatColor.DARK_AQUA.toString())
		.replace("&1", ChatColor.DARK_BLUE.toString())
		.replace("&9", ChatColor.BLUE.toString())
		.replace("&d", ChatColor.LIGHT_PURPLE.toString())
		.replace("&5", ChatColor.DARK_PURPLE.toString())
		.replace("&f", ChatColor.WHITE.toString())
		.replace("&7", ChatColor.GRAY.toString())
		.replace("&8", ChatColor.DARK_GRAY.toString())
		.replace("&0", ChatColor.BLACK.toString());
	}

	public static String removeColor(String string){
		return string
		.replace(ChatColor.DARK_RED.toString(), "")
		.replace(ChatColor.RED.toString(), "")
		.replace(ChatColor.GOLD.toString(), "")
		.replace(ChatColor.YELLOW.toString(), "")
		.replace(ChatColor.DARK_GREEN.toString(), "")
		.replace(ChatColor.GREEN.toString(), "")
		.replace(ChatColor.AQUA.toString(), "")
		.replace(ChatColor.DARK_AQUA.toString(), "")
		.replace(ChatColor.DARK_BLUE.toString(), "")
		.replace(ChatColor.BLUE.toString(), "")
		.replace(ChatColor.LIGHT_PURPLE.toString(), "")
		.replace(ChatColor.DARK_PURPLE.toString(), "")
		.replace(ChatColor.WHITE.toString(), "")
		.replace(ChatColor.GRAY.toString(), "")
		.replace(ChatColor.DARK_GRAY.toString(), "")
		.replace(ChatColor.BLACK.toString(), "")
		.replace("&4", "")
		.replace("&c", "")
		.replace("&6", "")
		.replace("&e", "")
		.replace("&2", "")
		.replace("&a", "")
		.replace("&b", "")
		.replace("&3", "")
		.replace("&1", "")
		.replace("&9", "")
		.replace("&d", "")
		.replace("&5", "")
		.replace("&f", "")
		.replace("&7", "")
		.replace("&8", "")
		.replace("&0", "");
	}	
	

	public static boolean isConsole(CommandSender sender)
	{
		
		if((sender instanceof Player) == false)
		{
			sender.sendMessage("This isnt a command for the console silly.");
			return true;
		}else{
			return false;
		}
		
	}
	
	public static boolean isNum(Object num)
	{
		if(num instanceof Integer)
		{
			return true;
		}else if (num instanceof String)
		{
			return isNum((String) num);
		}
		return false;
	}
	
	public static boolean isNum(String num)
	{
		char[] only = {'0','1','2','3','4','5','6','7','8','9'};
		boolean result;
		char[] charNum = num.toCharArray();
		int i = 0;
		
		//if start number is -, start loop at char 1
		if(charNum[0] == '-')
		{
			i = 1;
		}
		
		for(;i > Array.getLength(charNum);i++)
		{
			result = false;
			for(char currentTest : only)
			{
				if( currentTest == charNum[i])
				{
					result = true;
				}
			}
			if(result == false)
			{
				return false;
			}
		}
		return true;
	}

	public static List<Entity> getNearbyMobs(Location location, double distance){
		List<Entity> entities = getNearbyEntities(location, distance);

		for(int i = 0; i < entities.size(); i++){
			if(!(
					entities.get(i) instanceof Chicken
					|| entities.get(i) instanceof Cow
					|| entities.get(i) instanceof Creeper
					|| entities.get(i) instanceof Ghast
					|| entities.get(i) instanceof Monster
					|| entities.get(i) instanceof Pig
					|| entities.get(i) instanceof PigZombie
					|| entities.get(i) instanceof Sheep
					|| entities.get(i) instanceof Skeleton
					|| entities.get(i) instanceof Slime
					|| entities.get(i) instanceof CaveSpider
					|| entities.get(i) instanceof Squid
					|| entities.get(i) instanceof Wolf
					|| entities.get(i) instanceof Zombie
					|| entities.get(i) instanceof Enderman
					)){
				entities.remove(i);
				i--;
			}
		}
		return entities;
	}
	
	public static List<Entity> getNearbyEntities(Location location, double distance){
		List<Entity> entities = new LinkedList<Entity>();

		for(Entity e : location.getWorld().getEntities()){
			if(getDistance(location, e.getLocation()) <= distance){
				entities.add(e);
			}
		}
		return entities;
	}
	
	public static double getDistance(Location l1, Location l2){
		return sutractIgnoreNegative(l1.getX(), l2.getX()) + sutractIgnoreNegative(l1.getY(), l2.getY()) + sutractIgnoreNegative(l1.getZ(), l2.getZ());
	}

	public static double getDistanceIgnoreY(Location l1, Location l2){
		return sutractIgnoreNegative(l1.getX(), l2.getX()) + sutractIgnoreNegative(l1.getZ(), l2.getZ());
	}

	public static double sutractIgnoreNegative(double d1, double d2){
		if(d1 - d2 >= 0){
			return d1 - d2;
		}
		return d2 - d1;
	}
	
}
